From 9acebec0b9b707bd8f525d3eb668f97d0d925094 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 24 Aug 2005 20:11:07 +0000 Subject: [PATCH] Avoid calling device_unregister from device_register callback. Also simplify code. Signed-off-by: Christian Limpach --- .../drivers/xen/blkback/xenbus.c | 102 ++++++++---------- 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c index 2f2fdfc3cd..2a445a3983 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c @@ -64,7 +64,7 @@ static void frontend_changed(struct xenbus_watch *watch, const char *node) = container_of(watch, struct backend_info, watch); /* If other end is gone, delete ourself. */ - if (!xenbus_exists(be->frontpath, "")) { + if (node && !xenbus_exists(be->frontpath, "")) { xenbus_rm(be->dev->nodename, ""); device_unregister(&be->dev->dev); return; @@ -139,62 +139,22 @@ static void backend_changed(struct xenbus_watch *watch, const char *node) { int err; char *p; - char *frontend; long int handle, pdev; struct backend_info *be = container_of(watch, struct backend_info, backend_watch); struct xenbus_device *dev = be->dev; - frontend = NULL; - err = xenbus_gather(dev->nodename, - "frontend-id", "%li", &be->frontend_id, - "frontend", NULL, &frontend, - NULL); - if (XENBUS_EXIST_ERR(err) || - strlen(frontend) == 0 || !xenbus_exists(frontend, "")) { - /* If we can't get a frontend path and a frontend-id, - * then our bus-id is no longer valid and we need to - * destroy the backend device. - */ - goto device_fail; - } - if (err < 0) { - xenbus_dev_error(dev, err, - "reading %s/frontend or frontend-id", - dev->nodename); - goto device_fail; - } - - if (!be->frontpath || strcmp(frontend, be->frontpath)) { - if (be->watch.node) - unregister_xenbus_watch(&be->watch); - if (be->frontpath) - kfree(be->frontpath); - be->frontpath = frontend; - frontend = NULL; - be->watch.node = be->frontpath; - be->watch.callback = frontend_changed; - err = register_xenbus_watch(&be->watch); - if (err) { - be->watch.node = NULL; - xenbus_dev_error(dev, err, - "adding frontend watch on %s", - be->frontpath); - goto device_fail; - } - } - err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev); if (XENBUS_EXIST_ERR(err)) - goto out; + return; if (err < 0) { xenbus_dev_error(dev, err, "reading physical-device"); - goto device_fail; + return; } if (be->pdev && be->pdev != pdev) { printk(KERN_WARNING "changing physical-device not supported\n"); - goto device_fail; + return; } be->pdev = pdev; @@ -215,32 +175,25 @@ static void backend_changed(struct xenbus_watch *watch, const char *node) err = PTR_ERR(be->blkif); be->blkif = NULL; xenbus_dev_error(dev, err, "creating block interface"); - goto device_fail; + return; } err = vbd_create(be->blkif, handle, be->pdev, be->readonly); if (err) { xenbus_dev_error(dev, err, "creating vbd structure"); - goto device_fail; + return; } - frontend_changed(&be->watch, be->frontpath); + /* Pass in NULL node to skip exist test. */ + frontend_changed(&be->watch, NULL); } - - out: - if (frontend) - kfree(frontend); - return; - - device_fail: - device_unregister(&be->dev->dev); - goto out; } static int blkback_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { struct backend_info *be; + char *frontend; int err; be = kmalloc(sizeof(*be), GFP_KERNEL); @@ -263,9 +216,46 @@ static int blkback_probe(struct xenbus_device *dev, dev->data = be; + frontend = NULL; + err = xenbus_gather(dev->nodename, + "frontend-id", "%li", &be->frontend_id, + "frontend", NULL, &frontend, + NULL); + if (XENBUS_EXIST_ERR(err)) + goto free_be; + if (frontend && + (strlen(frontend) == 0 || !xenbus_exists(frontend, ""))) { + /* If we can't get a frontend path and a frontend-id, + * then our bus-id is no longer valid and we need to + * destroy the backend device. + */ + goto free_be; + } + if (err < 0) { + xenbus_dev_error(dev, err, + "reading %s/frontend or frontend-id", + dev->nodename); + goto free_be; + } + + be->frontpath = frontend; + be->watch.node = be->frontpath; + be->watch.callback = frontend_changed; + err = register_xenbus_watch(&be->watch); + if (err) { + be->watch.node = NULL; + xenbus_dev_error(dev, err, + "adding frontend watch on %s", + be->frontpath); + goto free_be; + } + backend_changed(&be->backend_watch, dev->nodename); return err; + free_be: + if (frontend) + kfree(frontend); kfree(be); return err; } -- 2.30.2